package org.sang.utils;

import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;
import org.sang.pojo.CustomUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class JwtTokenUtil {
    // 秘钥
    private static final String SECRET = "exam2023#";
    // 过期时间24小时
    private static final int EXPIRE_SECONDS = 24*3600;

    private final static Logger logger = LoggerFactory.getLogger(JwtTokenUtil.class);

    public static String genAuthenticatedToken(CustomUser customUser){
        Calendar expireDate = Calendar.getInstance();
        expireDate.add(Calendar.SECOND, EXPIRE_SECONDS);
        String[] roleCodes = new String[customUser.getRoles().size()];
        for(int i=0; i<customUser.getRoles().size(); i++){
            roleCodes[i] = customUser.getRoles().get(i).getRoleCode();
        }
        return JWT.create().withJWTId("user"+customUser.getId())
                .withClaim("id", customUser.getId())
                .withClaim("username", customUser.getUsername())
                .withClaim("nickname", customUser.getUsername())
                .withClaim("phoneNum", customUser.getPhoneNum())
                .withClaim("email", customUser.getEmail())
                .withArrayClaim("roles", roleCodes)
                .withIssuer("admin")
                .withKeyId(UUID.randomUUID().toString().replaceAll("-", ""))
                .withIssuedAt(new Date(System.currentTimeMillis()))
                .withExpiresAt(expireDate.getTime())
                .sign(Algorithm.HMAC256(SECRET));
    }

    public static Map<String, Object> verifyJwtToken(String jwtToken){
        DecodedJWT decodedJWT = JWT.decode(jwtToken);
        Map<String, Claim> claimMap = decodedJWT.getClaims();
        Claim expireClaim = claimMap.get("exp");
        Date expireDate = expireClaim.asDate();
        logger.info("expireDate:"+ DateUtil.format(expireDate, "yyyy-MM-dd HH:mm:ss"));
        Map<String, Object> verifyMap = new HashMap<>();
        if(expireDate.before(new Date(System.currentTimeMillis()))){
            logger.info("jwtToken expired");
            // token 超时
            verifyMap.put("status", 406);
            return verifyMap;
        }
        String username = claimMap.get("username").asString();
        Long phoneNum = claimMap.get("phoneNum").asLong();
        logger.info("username:{},phoneNum:{}", username, phoneNum);
        if(StringUtils.isNotEmpty(username) && phoneNum!=null){
            // token 有效
            verifyMap.put("status", 200);
            verifyMap.put("username", username);
            return verifyMap;
        }else{
            // token 无效
            verifyMap.put("status", 401);
            return verifyMap;
        }
    }

}
